package biz

import (
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
	"gitlab1.moolink.net/trade/backend/gen"
	"lab.com/conf"
	"lab.com/consts"
	"lab.com/define/errorcode"
	"lab.com/gen/entity"
	"lab.com/request"
)

type achievementBiz struct {
}

// Achievement  科研成果
var Achievement = achievementBiz{}

// List 科研成果列表
func (ach *achievementBiz) List(c *gin.Context, req request.AchievementListReq) (out request.AchievementListRes, err error) {
	ctx := conf.Span(c, "biz achievement list", nil)
	achModel := conf.LabGen.Achievement

	where := []gen.Condition{achModel.Status.Eq(consts.AchNormal), achModel.IsShow.Eq(consts.AchShow)}
	if req.IsAll == consts.AchInHome {
		where = append(where, achModel.IsHome.Eq(consts.AchInHome))
	}
	if req.Title != "" {
		where = append(where, achModel.Title.Like("%"+req.Title+"%"))
	}
	if req.Type != 0 {
		where = append(where, achModel.Type.Like(req.Type))
	}
	if req.StartTime != "" {
		if t, err := time.Parse("2006-01-02", req.StartTime); err != nil {
			return out, err
		} else {
			where = append(where, achModel.PublishTime.Gte(t))
		}
	}
	if req.EndTime != "" {
		if t, err := time.Parse("2006-01-02", req.EndTime); err != nil {
			return out, err
		} else {
			where = append(where, achModel.PublishTime.Lte(t))
		}
	}

	info, count, err := achModel.WithContext(ctx).Where(where...).Order(achModel.PublishTime).FindByPage(req.Offset, req.Size)
	if err != nil {
		return out, err
	}

	list := make([]request.AchievementBasicInfo, 0, len(info))
	for _, val := range info {
		list = append(list, request.AchievementBasicInfo{
			Id:          val.ID,
			Title:       val.Title,
			Abstract:    val.Abstract,
			Author:      val.Author,
			ImgPath:     val.ImgPath,
			Type:        val.Type,
			PublishTimt: val.PublishTime.Format("2006-01-02"),
		})
	}
	out.List = list
	out.Count = int(count)
	return out, nil
}

// Detail 科研成果详情
func (ach *achievementBiz) Detail(c *gin.Context, req request.AchievementDetailReq) (out request.AchievementDetailRes, err error) {
	ctx := conf.Span(c, "biz achievement detail", nil)
	achModel := conf.LabGen.Achievement

	info, err := achModel.WithContext(ctx).Where(achModel.ID.Eq(req.ID)).First()
	if err != nil {
		return out, err
	}

	out.Content = info.Content
	out.Id = info.ID
	out.Title = info.Title
	out.Abstract = info.Abstract
	out.Author = info.Author
	out.ImgPath = info.ImgPath
	out.Type = info.Type
	out.PublishTime = info.PublishTime.Format("2006-01-02")
	out.IsShow = info.IsShow
	out.IsHome = info.IsHome
	return out, nil
}

// Add 科研成果新增
func (ach *achievementBiz) Add(c *gin.Context, req request.AchievementAddReq) (err error) {
	ctx := conf.Span(c, "biz achievement add", nil)
	achModel := conf.LabGen.Achievement

	t, err := time.Parse("2006-01-02", req.PublishTime)
	if err != nil {
		return err
	}

	info := &entity.Achievement{
		Title:       req.Title,
		Abstract:    req.Abstract,
		Author:      req.Author,
		Content:     req.Content,
		Type:        req.Type,
		PublishTime: t,
		IsShow:      req.IsShow,
		IsHome:      req.IsHome,
		ImgPath:     req.ImgPath,
		CreateTime:  time.Now(),
		UpdateTime:  time.Now(),
	}

	err = achModel.WithContext(ctx).Create(info)
	return err
}

// Delete 科研成果删除
func (ach *achievementBiz) Delete(c *gin.Context, req request.AchievementDeleteReq) (err error) {
	ctx := conf.Span(c, "biz achievement delete", nil)
	achModel := conf.LabGen.Achievement

	info := &entity.Achievement{
		Status:     consts.AchDelete,
		UpdateTime: time.Now(),
	}

	_, err = achModel.WithContext(ctx).Select(achModel.UpdateTime, achModel.Status).Where(achModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Edit 科研成果编辑
func (ach *achievementBiz) Edit(c *gin.Context, req request.AchievementEditReq) (err error) {
	ctx := conf.Span(c, "biz achievement edit", nil)
	achModel := conf.LabGen.Achievement

	t, err := time.Parse("2006-01-02", req.PublishTime)
	if err != nil {
		fmt.Println(err)
		return err
	}

	info := &entity.Achievement{
		Title:       req.Title,
		Abstract:    req.Abstract,
		Author:      req.Author,
		Content:     req.Content,
		Type:        req.Type,
		PublishTime: t,
		IsShow:      req.IsShow,
		IsHome:      req.IsHome,
		ImgPath:     req.ImgPath,
		UpdateTime:  time.Now(),
	}

	_, err = achModel.WithContext(ctx).Select(achModel.Title, achModel.Abstract, achModel.Author, achModel.Content,
		achModel.Type, achModel.PublishTime, achModel.IsShow, achModel.IsHome, achModel.ImgPath, achModel.UpdateTime).
		Where(achModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Show 科研成果展示
func (ach *achievementBiz) Show(c *gin.Context, req request.AchievementShowReq) (err error) {
	ctx := conf.Span(c, "biz achievement show", nil)
	achModel := conf.LabGen.Achievement

	info := &entity.Achievement{
		IsShow:     req.IsShow,
		UpdateTime: time.Now(),
	}

	_, err = achModel.WithContext(ctx).Select(achModel.UpdateTime, achModel.IsShow).Where(achModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// Home 科研成果首页展示
func (ach *achievementBiz) Home(c *gin.Context, req request.AchievementHomeReq) (err error) {
	ctx := conf.Span(c, "biz achievement home", nil)
	achModel := conf.LabGen.Achievement

	if count, err := achModel.WithContext(ctx).Where(achModel.IsHome.Eq(consts.AchInHome), achModel.IsShow.Eq(consts.AchShow),
		achModel.Status.Eq(consts.AchNormal)).Count(); err != nil {
		return err
	} else if count > 8 {
		return errorcode.New(errorcode.ErrService, "首页展示个数超过限制！", nil)
	}

	info := &entity.Achievement{
		IsHome:     req.IsHome,
		UpdateTime: time.Now(),
	}

	_, err = achModel.WithContext(ctx).Select(achModel.UpdateTime, achModel.IsHome).Where(achModel.ID.Eq(req.ID)).Updates(info)
	return err
}

// List 科研成果列表
func (ach *achievementBiz) ListInManage(c *gin.Context, req request.AchievementListInManageReq) (out request.AchievementListInManageRes, err error) {
	ctx := conf.Span(c, "biz achievement list in manage", nil)
	achModel := conf.LabGen.Achievement

	where := []gen.Condition{achModel.Status.Eq(consts.AchNormal)}
	if req.Title != "" {
		where = append(where, achModel.Title.Like("%"+req.Title+"%"))
	}
	if req.Type != 0 {
		where = append(where, achModel.Type.Like(req.Type))
	}
	if req.StartTime != "" {
		if t, err := time.Parse("2006-01-02", req.StartTime); err != nil {
			return out, err
		} else {
			where = append(where, achModel.PublishTime.Gte(t))
		}
	}
	if req.EndTime != "" {
		if t, err := time.Parse("2006-01-02", req.EndTime); err != nil {
			return out, err
		} else {
			where = append(where, achModel.PublishTime.Lte(t))
		}
	}

	info, count, err := achModel.WithContext(ctx).Where(where...).Order(achModel.PublishTime.Desc()).FindByPage(req.Offset, req.Size)
	if err != nil {
		return out, err
	}

	list := make([]request.AchievementInfo, 0, len(info))
	for _, val := range info {
		list = append(list, request.AchievementInfo{
			Id:          val.ID,
			Title:       val.Title,
			Abstract:    val.Abstract,
			Author:      val.Author,
			ImgPath:     val.ImgPath,
			Type:        val.Type,
			PublishTime: val.PublishTime.Format("2006-01-02"),
			IsShow:      val.IsShow,
			IsHome:      val.IsHome,
		})
	}
	out.List = list
	out.Count = int(count)
	return out, nil
}
